﻿//-----------------------------------------------------------------------
// <copyright file="LoggerBase.cs" company="OpenSource">
//     All code is Microsoft Public License (Ms-PL)
// </copyright>
// <history>
// 2013.02  Created         Chris Hand
// </history>
//-----------------------------------------------------------------------
namespace OpenSource.TumblrAPI.Support
{
    /// <summary>
    /// The abstract base class common to all types of loggers
    /// </summary>
    public abstract class LoggerBase : ILogger
    {
        /// <summary>
        /// Initializes a new instance of the LoggerBase class
        /// </summary>
        /// <param name="flags">The flags that indicate which category of log messages should be displayed</param>
        protected LoggerBase(LogFlag flags)
        {
            this.Flags = flags;
        }

        /// <summary>
        /// Gets the flags that indicate which category of log messages should be displayed
        /// </summary>
        protected LogFlag Flags { get; private set; }

        /// <summary>
        /// Debug messages should be used for a noisy spew of data that would help figure out specific problems
        /// </summary>
        /// <param name="message">Whatever you want to say</param>
        public void Debug(string message)
        {
            if (this.Active(LogFlag.Debug))
            {
                this.WriteLog(LogFlag.Debug, message);
            }
        }

        /// <summary>
        /// Debug messages should be used for a noisy spew of data that would help figure out specific problems
        /// </summary>
        /// <param name="format">The format of your message, same as String.Format</param>
        /// <param name="args">The values to go into the format</param>
        public void Debug(string format, params object[] args)
        {
            this.Debug(string.Format(format, args));
        }

        /// <summary>
        /// Trace messages should be used to indicate when you have entered or left a section of code
        /// </summary>
        /// <param name="message">Whatever you want to say</param>
        public void Trace(string message)
        {
            if (this.Active(LogFlag.Trace))
            {
                this.WriteLog(LogFlag.Trace, message);
            }
        }

        /// <summary>
        /// Trace messages should be used to indicate when you have entered or left a section of code
        /// </summary>
        /// <param name="format">The format of your message, same as String.Format</param>
        /// <param name="args">The values to go into the format</param>
        public void Trace(string format, params object[] args)
        {
            this.Trace(string.Format(format, args));
        }

        /// <summary>
        /// Info messages provide minor details - the results of specific actions, etc.
        /// </summary>
        /// <param name="message">Whatever you want to say</param>
        public void Info(string message)
        {
            if (this.Active(LogFlag.Info))
            {
                this.WriteLog(LogFlag.Info, message);
            }
        }

        /// <summary>
        /// Info messages provide minor details - the results of specific actions, etc.
        /// </summary>
        /// <param name="format">The format of your message, same as String.Format</param>
        /// <param name="args">The values to go into the format</param>
        public void Info(string format, params object[] args)
        {
            this.Info(string.Format(format, args));
        }

        /// <summary>
        /// Should only be used to indicate that the app is about to crash hard.
        /// </summary>
        /// <param name="message">Whatever you want to say</param>
        public void Fatal(string message)
        {
            this.WriteLog(LogFlag.Fatal, message);
        }

        /// <summary>
        /// Should only be used to indicate that the app is about to crash hard.
        /// </summary>
        /// <param name="format">The format to display the information in, same as string.Format</param>
        /// <param name="args">The information to display</param>
        public void Fatal(string format, params object[] args)
        {
            this.Fatal(string.Format(format, args));
        }

        /// <summary>
        /// Places where we need to come back and fix something
        /// </summary>
        /// <param name="message">Helpful information</param>
        public void TODO(string message)
        {
            if (this.Active(LogFlag.TODO))
            {
                this.WriteLog(LogFlag.TODO, message);
            }
        }

        /// <summary>
        /// Determine if we should write to the log
        /// </summary>
        /// <param name="flag">The specified output flag</param>
        /// <returns>If true, write to the log</returns>
        protected bool Active(LogFlag flag)
        {
            return flag == (this.Flags & flag);
        }

        /// <summary>
        /// The method that decides how the log file is written
        /// </summary>
        /// <param name="flag">The log flag that is enabled to allow this message to be written</param>
        /// <param name="message">The message to write</param>
        protected abstract void WriteLog(LogFlag flag, string message);
    }
}
